<?php
	//Notification class
	class Notification {
		private $notification_id;
		private $user_id;
		private $related_id;
		private $log_id;
		private $notification_type_id;
		private $notification_message;
		private $notification_time;

		//Note: Constructor does not set ID however insert() and Notification::createNotification() sets ID
		//		Use Notification::createNotification() for manipulation of Notification
		
		//Constructor for Notification
		//		
		//Param: user id, type id, message, related id, time
		function __construct($user_id, $notification_type_id, $notification_message, $related_id, $log_id, $notification_time) {
			$this->setUserID($user_id);
			$this->setTypeID($notification_type_id);
			$this->setMessage($notification_message);
			$this->setRelatedID($related_id);
			$this->setLogID($log_id);
			$this->setTime($notification_time);
		}
		
		//Create and return message for Notification
		//Add the difference between time the notification is made and now
		//
		//Return: message
		function __toString() {
			$timeDiff  = $this->calcTimeDiff();
			if ($timeDiff < 60) {
				$message = $this->getMessage() . ' About ' . $timeDiff . ' seconds ago.';
			} else if ($timeDiff >= 60 && $timeDiff < 3600 && floor($timeDiff/60) == 1) {
				$message = $this->getMessage() . ' About ' . floor($timeDiff/60) . ' minute ago.';			
			} else if ($timeDiff >= 60 && $timeDiff < 3600) {
				$message = $this->getMessage() . ' About ' . floor($timeDiff/60) . ' minutes ago.';
			} else if ($timeDiff >= 3600 && $timeDiff < 86400 && floor($timeDiff/3600) == 1) {
				$message = $this->getMessage() . ' About ' . floor($timeDiff/3600) . ' hour ago.';
			} else if ($timeDiff >= 3600 && $timeDiff < 86400) {
				$message = $this->getMessage() . ' About ' . floor($timeDiff/3600) . ' hours ago.';
			} else if ($timeDiff >= 86400 && floor($timeDiff/86400) == 1){
				$message = $this->getMessage() . ' About ' . floor($timeDiff/86400) . ' day ago.';
			} else {
				$message = $this->getMessage() . ' About ' . floor($timeDiff/86400) . ' days ago.';
			}
			return $message;
		}
		
		//Setter for Notification ID
		function setNotificationID($val) {
			$this->notification_id = $val;
		}
		//Getter for Notification ID
		function getNotificationID() {
			return $this->notification_id;
		}
		
		//Setter for User ID
		function setUserID($val) {
			$this->user_id = $val;
		}
		//Getter for User ID
		function getUserID() {
			return $this->user_id;
		}
		
		//Setter for Type ID
		function setTypeID($val) {
			$this->notification_type_id = $val;
		}
		//Getter for Type ID
		function getTypeID() {
			return $this->notification_type_id;
		}
		
		//Setter for Notification message
		function setMessage($val) {
			$this->notification_message = $val;
		}
		//Getter for Notification message
		function getMessage() {
			return $this->notification_message;
		}
		
		//Setter for Notification related ID
		function setRelatedID($val) {
			$this->related_id = $val;
		}
		//Getter for Notification related ID
		function getRelatedID() {
			return $this->related_id;
		}		
		
		//Setter for Notification log ID
		function setLogID($val) {
			$this->log_id = $val;
		}
		//Getter for Notification log ID
		function getLogID() {
			return $this->log_id;
		}
		
		//Setter for Notification time
		function setTime($val = null) {
			if ($val === null) {
				$this->notification_time = date(DATE_FORMAT);
			} else {
				$this->notification_time = $val;
			}
		}					
		//Getter for Notification time
		function getTime() {
			return $this->notification_time;
		}
		
		//Calculate the time difference between notification time and now
		//
		//Return: time difference
		function calcTimeDiff() {
			
			$firstTime=strtotime($this->getTime());
			$lastTime=strtotime(date(DATE_FORMAT));
			$timeDiff=$lastTime-$firstTime;
			
			return intval($timeDiff);
		}

		//Insert new Notification info into database
		//
		//Return: Notification ID or O		
		function insert() {
			$db = Database::get();
			$query = "INSERT INTO " . NOTIFICATION_TABLE . " 
				(user_id, notification_type_id, notification_message, related_id, log_id, created_at)
				VALUES(?, ?, ?, ?, ?, ?);";
			$stmt = $db->prepare($query);
			if ($stmt) {

				$user_id = $this->getUserID();
				$notification_type_id = $this->getTypeID();
				//Encode message
				$notification_message = base64_encode($this->getMessage());
				
				$related_id = $this->getRelatedID();
				$log_id = $this->getLogID();
				$notification_time = $this->getTime();
				
				$stmt->bind_param("ddsdds", $user_id, $notification_type_id, $notification_message, $related_id, $log_id, $notification_time);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$notification_id = $stmt->insert_id;
				$this->setNotificationID($notification_id);
				$stmt->close();
				
				// Send notification to the android app as well.
				User::pushAndroidNotification($user_id, $notification_id, $notification_time);
				
				return $notification_id;
			}
			return 0;
		}

		//Remove Notification from database
		//
		//Return: true or false		
		function remove() {
			$db = Database::get();
			$query = "DELETE FROM " . NOTIFICATION_TABLE . " 
				WHERE notification_id = ?;";
			$stmt = $db->prepare($query);
			if ($stmt) {
				$notification_id = $this->getNotificationID();
				
				$stmt->bind_param("d", $notification_id);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$stmt->close();
				return true;
			}
			return false;
		}		

		//Find Notification ID given the user id, type id and related id
		//
		//Param: user id, type id, related id
		//Return: notification id
		static function findID($user, $type, $related) {
			$db = Database::get();
			$id = 0;
			$query = "SELECT notification_id FROM " . NOTIFICATION_TABLE . "
					  WHERE user_id = ? AND notification_type_id = ? 
					  AND related_id = ?;";
			$stmt = $db->prepare($query);
			if ($stmt) {
				$stmt->bind_param("ddd", $user, $type, $related);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$stmt->bind_result($id);
				$stmt->fetch() or $id = 0;
				$stmt->close();
			} else {
				die('Invalid query for Notification: ' . $db->error);
			}
			return intval($id);
		}	

		//Find Notification ID given the user id, type id, related id and log id
		//
		//Param: user id, type id, related id, log id
		//Return: notification id	
		static function findIDWithLog($user, $type, $related, $log) {
			$db = Database::get();
			$id = 0;
			$query = "SELECT notification_id FROM " . NOTIFICATION_TABLE . "
					  WHERE user_id = ? AND notification_type_id = ? 
					  AND related_id = ? AND log_id = ?;";
			$stmt = $db->prepare($query);
			if ($stmt) {
				$stmt->bind_param("ddds", $user, $type, $related, $log);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$stmt->bind_result($id);
				$stmt->fetch() or $id = 0;
				$stmt->close();
			} else {
				die('Invalid query for Notification: ' . $db->error);
			}
			return intval($id);
		}	
		
		//Add a new Notification type given the type name
		//
		//Param: notification type name
		//Return: notification type id			
		static function addType($name) {
			$db = Database::get();
			$query = "INSERT INTO " . NOTIFICATION_TYPE_TABLE . " 
				(notification_type_name) VALUES(?);";
			$stmt = $db->prepare($query);
			if ($stmt) {

				$stmt->bind_param("s", $name);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$notification_type_id = $stmt->insert_id;
				$stmt->close();
				return $notification_type_id;
			}
			return 0;
		}

		//Remove a Notification type given the type id
		//
		//Param: notification type id
		//Return: true or false	
		static function removeType($id) {
			$db = Database::get();
			$query = "DELETE FROM " . NOTIFICATION_TYPE_TABLE . " 
					  WHERE notification_type_id = ?;";
			$stmt = $db->prepare($query);
			if ($stmt) {
				$stmt->bind_param("d", $id);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$stmt->close();
				
				return true;
			}
			return false;
		}		

		//Find a Notification type name given the type id
		//
		//Param: notification type id
		//Return: notification type name	
		static function findTypeName($id) {
			$db = Database::get();
			$name = null;
			$query = "SELECT notification_type_name FROM " . NOTIFICATION_TYPE_TABLE . "
					  WHERE notification_type_id = ?;";
			$stmt = $db->prepare($query);
			if ($stmt) {
				$stmt->bind_param("d", $id);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$stmt->bind_result($name);
				$stmt->fetch() or $name = null;
				$stmt->close();
			} else {
				die('Invalid query for Notification: ' . $db->error);
			}
			return $name;
		}		

		//Find a Notification type id given the type name
		//
		//Param: notification type name
		//Return: notification type id			
		static function findTypeID($name) {
			$db = Database::get();
			$id = 0;
			$query = "SELECT notification_type_id FROM " . NOTIFICATION_TYPE_TABLE . "
					  WHERE notification_type_name = ?;";
			$stmt = $db->prepare($query);
			if ($stmt) {
				$stmt->bind_param("s", $name);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$stmt->bind_result($id);
				$stmt->fetch() or $id = 0;
				$stmt->close();
			} else {
				die('Invalid query for Notification: ' . $db->error);
			}
			return intval($id);
		}		
		
		//Get list of Notification type
		//
		//Return: List of Notification type
		static function getNotificationTypeList() {
			$notification_type_list = null;
			$db = Database::get();
			$query = "SELECT * FROM " . NOTIFICATION_TYPE_TABLE . ";";
			$stmt = $db->prepare($query);
			if ($stmt) {
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$result = $stmt->get_result();
				while ($row = $result->fetch_assoc()) {
					$notification_type_list[] = $row;
				} 
				$stmt->close();
			} else {
				die('Invalid query for Notification: ' . $db->error);
			}
			return $notification_type_list;
		}
		
		//Get list of Notification given the user id, start and show
		//Start is the starting row to display
		//Show is to filter the number of rows to display
		//
		//Param: user id, start, show
		//Return: List of Notification
		static function getNotificationList($user_id, $start, $show) {
			$notification_list = null;
			$db = Database::get();
			$query = "SELECT * FROM " . NOTIFICATION_TABLE . " 
				WHERE user_id = ? ORDER BY created_at DESC LIMIT ?, ?;";
			$stmt = $db->prepare($query);
			if ($stmt) {			
				$stmt->bind_param("ddd", $user_id, $start, $show);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$result = $stmt->get_result();
				while($row = $result->fetch_assoc()) {
					$notification_list[] = $row;
				} 
				$stmt->close();
			}
			
			return $notification_list;
		}		

		//Create Notification object given the ID by taking information from the database
		//Information taken from the database: user id, type id, message, related id, log id,
		//	time
		//
		//Param: user id
		//Return: Notification object			
		static function createNotification($id) {
			$db = Database::get();
			$query = "SELECT * FROM " . NOTIFICATION_TABLE . "
					  WHERE notification_id = ?;";
			$stmt = $db->prepare($query);
			if ($stmt) {
				$stmt->bind_param("d", $id);
				$stmt->execute() or die('Invalid query for Notification: ' . $db->error);
				$result = $stmt->get_result();
				$notification_row = null;
				if ($row = $result->fetch_assoc()) {
					$notification_row = $row;
				} 
				$stmt->close();
			} else {
				die('Invalid query for Notification: ' . $db->error);
			}
			
			$notification = null;
			if ($notification_row !== null) {
				$user_id = $notification_row['user_id'];
				$notification_type_id = $notification_row['notification_type_id'];
				$notification_message = base64_decode($notification_row['notification_message']);	
				$related_id = $notification_row['related_id'];				
				$log_id = $notification_row['log_id'];				
				$notification_time = $notification_row['created_at'];

				$notification = new Notification($user_id, $notification_type_id, $notification_message, $related_id, $log_id, $notification_time);
				$notification->setNotificationID($id);
				}
				
			return $notification;
		}
		
		
	}
?>